package AnnotationLearn;

import com.sun.jdi.Value;
import org.junit.jupiter.api.Test;


import javax.swing.text.StyledEditorKit;
import java.lang.annotation.Annotation;
import java.util.ArrayList;

/**
 * @author Lenl
 * @version v1.0
 * @create 2021-06-04 16:46
 * @description 注解的使用
 *
 * 1.介绍
 *   jdk5.0的新特性
 *   Annotation代码中的特殊标记
 *   重要！框架中
 * 2.Annotation的使用示例
 *  示例一：生成文档的相关注解
 *  示例二：在编译时进行格式检查
 * //@Override:限定重写父类方法，只能用于方法
 * //@deprecated:表示修饰的元素（类、方法等）已过时。
 * //@SuppressWarnings:抑制警告
 * 3.自定义注解
 *  ①注解声明：@interface
 *  ②内部定义成员，通常用value表示
 *  ③可以指定成员默认值，使用default表示
 *  ④如果自定义注解没有成员，表明只是一个标识作用，如果有成员，需要指明成员值
 *  ！自定义注解必须配上注解的信息处理流程（使用反射）才有意义
 *  自定义注解通常会指明两个元注解：Retention、Target
 * 4.jdk中提供的元注解：修饰其他注解的注解
 *  Retention:指定所修饰的注解的生命周期：SOURCE\CLASS（默认）\RUNTIME
 *              只有声明为RUNTIME的注解可以通过反射读取
 *  Target:用于指定被修饰的注解能被用于哪些程序元素
 *
 *  Documented:表示所修饰的注解在被javadoc解析时保留
 *
 *  Inherited:被注解修饰的类的子类自动继承该注解
 *
 *  5.通过反射获取注解
 *
 *  6。jdk8中的新特性
 *      6.1可重复注解:①在MyAnnotation上声明@Repeatable,成员值为MyAnnotations.class
 *               ②MyAnnotation的Target和Retention等元注解和MyAnnotations相同
 *      6.2类型注解：
 *          ElementType.TYPE_PARAMETER表示该注解能写在类型变量声明语句中（如泛型声明）
 *          ElementType.TYPE_USE 表示该注解能下载适用类型的任何语句中。
 *
 */
public class AnnotationTest {
    @Test
    public void test(){
        Class cls=Student.class;
        //声明为Retention(RetentionPolicy.RUNTIME)的注解才能被反射读取到
        Annotation[] annos=cls.getAnnotations();
        System.out.println(annos.length);
        for (int i=0;i<annos.length;i++){
            System.out.println(annos[i]);
        }
    }
}

//JDK8以前想重复注解
//@MyAnnotations({@MyAnnotation(value="123"),@MyAnnotation(value="321")})
//JDK8新特性
@MyAnnotation(value = "123")
@MyAnnotation(value = "213")
class Student extends  Person{

}

@MyAnnotation(value = "hi")
class Person{
    private String name;
    private  int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Person() {
    }
}

//给MyAnnotation的Target添加TYPE_PARAMETER
class Generic<@MyAnnotation T>{
    //给MyAnnotation的Target添加TYPE_USE
    public  void show() throws RuntimeException{
        ArrayList<@MyAnnotation String> list=new ArrayList<>();
        int num=(@MyAnnotation int)10L;
    }

}